package com.sophossystems.client.asmon.dao.spring;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.transform.Transformers;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.transaction.annotation.Transactional;

import com.sophossystems.client.asmon.dao.ModuleDao;
import com.sophossystems.client.asmon.dto.ModuleDTO;
import com.sophossystems.client.asmon.dto.ModulePkDTO;
import com.sophossystems.client.asmon.exceptions.DaoException;
import com.sophossystems.client.asmon.hibernate.Module;

public class ModuleDaoImpl extends AbstractDAO implements  ModuleDao
{
	private static Logger log = Logger.getLogger(ModuleDaoImpl.class);

	/**
	 * Method 'insert'
	 * 
	 * @param dto
	 * @return ActivityPk
	 */
	@Override
	@Transactional
	public ModulePkDTO insert(final ModuleDTO dto){
		ModulePkDTO exito =null ;
	try {
		 exito = (ModulePkDTO) getHibernateTemplate().execute(new HibernateCallback() {
			/**
			 * {@inheritDoc}
			 * 
			 * @see org.springframework.orm.hibernate3.HibernateCallback#doInHibernate(org.hibernate.Session)
			 */
			@Override
			public Object doInHibernate(Session session)
					throws HibernateException, SQLException {
			    Transaction tx = session.beginTransaction();
			    ModulePkDTO pk = null;
			    Module module = new Module();
			    module.mapper(dto);
			    session.save(module);
			    tx.commit();
			    try{
			    	//revisar las busquedas
			    	//cambia de ModuleDTO a ModulePkDTO
			    	ModulePkDTO res = findLastInsert();
			    	pk = new ModulePkDTO();
			    	pk.setIdModule(res.getIdModule());
			    }catch (DaoException es) {
					
			    	throw new HibernateException("Insersion: " +es.getMessage());
				}
				return pk;
			
				
			}

			
		});
	///	 return exito;
	} catch (final Exception e) {
		logger.error("Error: getModule, cause: " + e.getMessage(), e);
		
	}
	return exito;
}

		
	/** 
	 * Updates a single row in the Activity table.
	 */
	@Override
	@Transactional
	public void update(final ModuleDTO dto) throws DaoException
	{
		try {
			 getHibernateTemplate().execute(new HibernateCallback() {
				/**
				 * {@inheritDoc}
				 * 
				 * @see org.springframework.orm.hibernate3.HibernateCallback#doInHibernate(org.hibernate.Session)
				 */
				@Override
				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
					ModulePkDTO pk = null;
					ModuleDTO res = null;
					Transaction tx = session.beginTransaction();
					// Aqui primero se busca si existe el registro
					try {
						log.debug(" se busca id = " + dto.getIdModule());
						res = findByPrimaryKey(dto
								.getIdModule());
						log.debug("el id a actualizar es: " + res.getIdModule());
						pk = new ModulePkDTO();
						pk.setIdModule(res.getIdModule());
					} catch (DaoException es) {
						throw new HibernateException(
								"Update ModuleDao: "
										+ es.getMessage());
					}
					///aqui se actualizar los campos y con los de la entrada  
					//cuidado de actualiza todo.
					Module persis = new Module();
					persis.mapper(dto);
					persis.setIdModule(res.getIdModule());
					session.update(persis);
					tx.commit();
					return null;
				}		
			});
		} catch (final Exception e) {
			logger.error("Error: al actualizar Module, cause: " + e.getMessage(), e);
			throw new DaoException("Error: getModule, cause: " + e.getMessage());
		}
	
		
	
	}

	/** 
	 * Deletes a single row in the Activity table.
	 */
	@Override
	@Transactional
	public void delete(final ModulePkDTO pk) throws DaoException
	{
		
		
		try {
			 getHibernateTemplate().execute(new HibernateCallback() {
				/**
				 * {@inheritDoc}
				 * 
				 * @see org.springframework.orm.hibernate3.HibernateCallback#doInHibernate(org.hibernate.Session)
				 */
				@Override
				public Object doInHibernate(Session session)
						throws HibernateException, SQLException {
				    Transaction tx = session.beginTransaction();
				    Module module = (Module)session.load(Module.class,pk.getIdModule() );
				    session.delete(module);
					tx.commit();
					return null;
				}		
			});
		} catch (final Exception e) {
			logger.error("Error: getActivity, cause: " + e.getMessage(), e);
			throw new DaoException("Error: getActivity, cause: " + e.getMessage());
		}
	}
	

	

	/**
	 * Method 'getTableName'
	 * 
	 * @return String
	 */
	public String getTableName()
	{
		return "Module";
	}

	/** 
	 * Returns all rows from the Module table that match the criteria 'idModule = :idModule'.
	 */
	@Override
	@Transactional
	public ModuleDTO findByPrimaryKey(final int idModule)
			throws DaoException	{
		ModuleDTO module = null;
		try {
			module = (ModuleDTO)getHibernateTemplate().execute(
					new HibernateCallback() {
						
						@SuppressWarnings("unchecked")
						@Override
						public Object doInHibernate(Session session) throws HibernateException,
								SQLException {
							
							ModuleDTO module = null;
							Query oQuery = session.createQuery("SELECT m.idModule as idModule , m.description as description," +
									" m.idSystem as idSystem FROM " + getTableName() + " m WHERE m.idModule = :id_module");
							oQuery.setInteger("id_module", idModule);
							List<ModuleDTO> lista = oQuery.setResultTransformer(
									Transformers.aliasToBean(ModuleDTO.class)).list();
							if(lista != null && lista.size() > 0){
								module = lista.get(0);
								return module;
							}else{
								
							}
							return module;
						}
					});
//					jdbcTemplate.query("SELECT idModule, Description, idSystem FROM " + getTableName() + " WHERE idModule = ?", this,idModule);
//			return list.size() == 0 ? null : list.get(0);
		}
		catch (Exception e) {
			logger.error("Error: Module, cause: " + e.getMessage(), e);
			throw new DaoException("Query failed", e);
		}
		return module;
	}

	/** 
	 * Returns all rows from the Module table that match the criteria ''.
	 */
	@Override
	@SuppressWarnings("unchecked")
	@Transactional
	public List<ModuleDTO> findAll() throws DaoException {
		List<ModuleDTO> module = null;
		try {
			module = (List<ModuleDTO>)getHibernateTemplate().execute(
					new HibernateCallback() {
						
						@Override
						public Object doInHibernate(Session session) throws HibernateException,
								SQLException {
						
							Query oQuery = session.createQuery("SELECT m.idModule as idModule , m.description as description," +
									" m.idSystem as idSystem FROM " + getTableName() + " m ORDER BY m.idModule");
							List<ModuleDTO> lista = oQuery
									.setResultTransformer(Transformers
											.aliasToBean(ModuleDTO.class)).list();
							return lista;
						}
					});
		}
		catch (Exception e) {
			logger.error("Error: Module, cause: " + e.getMessage(), e);
			throw new DaoException("Query failed", e);
		}
		return module;
	}

	/** 
	 * Returns all rows from the Module table that match the criteria 'idModule = :idModule'.
	 */
	@Override
	@Transactional
	public List<ModuleDTO> findWhereIdModuleEquals(final int idModule)
			throws DaoException{
		List<ModuleDTO> list = new ArrayList<ModuleDTO>();
		ModuleDTO modulo = this.findByPrimaryKey(idModule);
		list.add(modulo);
		return list;
		
	}

	/** 
	 * Returns all rows from the Module table that match the criteria 'Description = :description'.
	 */
	@Override
	@SuppressWarnings("unchecked")
	@Transactional
	public List<ModuleDTO> findWhereDescriptionEquals(final String description) throws DaoException
	{
		List<ModuleDTO> modulo = null;
		try {
			modulo = (List<ModuleDTO>) getHibernateTemplate().execute(
					new HibernateCallback() {
						/**
						 * {@inheritDoc}
						 * 
						 * @see org.springframework.orm.hibernate3.HibernateCallback#doInHibernate(org.hibernate.Session)
						 */
						@Override
						public Object doInHibernate(Session session)
								throws HibernateException, SQLException {
							final Query oQuery = session
									.createQuery("SELECT m.idModule as idModule, m.description as description, m.idSystem as idSystem FROM "
											+ getTableName()
											+ " m WHERE m.description = :description ORDER BY m.description");
							oQuery.setString("description", description);
							List<ModuleDTO> moduleDto = oQuery
									.setResultTransformer(
											Transformers
													.aliasToBean(ModuleDTO.class))
									.list();
							log.debug("Se obtuvo el resultado: "
									+ moduleDto.size());
							return moduleDto;
						}
					});
		} catch (final Exception e) {
			logger.error("Error: getModule, cause: " + e.getMessage(), e);
			throw new DaoException("Error: getModule, cause: "
					+ e.getMessage());
		}
		return modulo;
		
	}

	/** 
	 * Returns all rows from the Module table that match the criteria 'idSystem = :idSystem'.
	 
	@Transactional
	public List<ModuleDTO> findWhereIdSystemEquals(int idSystem) throws DaoException
	{
		try {
			return jdbcTemplate.query("SELECT idModule, Description, idSystem FROM " + getTableName() + " WHERE idSystem = ? ORDER BY idSystem", this,idSystem);
		}
		catch (Exception e) {
			logger.error("Error: Module, cause: " + e.getMessage(), e);
			throw new DaoException("Query failed", e);
		}
		
	}*/

	/** 
	 * Returns the rows from the Module table that matches the specified primary-key value.
	 
	public ModuleDTO findByPrimaryKey(ModulePkDTO pk) throws DaoException
	{
		return findByPrimaryKey( pk.getIdModule() );
	}*/

	@Override
	public ModulePkDTO findLastInsert() throws DaoException {
		ModulePkDTO module = null;
		try {
			module = (ModulePkDTO) getHibernateTemplate().execute(
					new HibernateCallback() {

						@Override
						public Object doInHibernate(Session session)
								throws HibernateException, SQLException {
							
							Query oQuery = session
									.createQuery("SELECT max(m.idModule) as idModule FROM "
											+ getTableName()
											+ " m ");
							
							ModulePkDTO moduleDto = (ModulePkDTO) oQuery
									.setResultTransformer(Transformers
											.aliasToBean(ModulePkDTO.class)).list().get(0);
							return moduleDto;
						}
					});
		
		} catch (Exception e) {
			logger.error("Error: ModuleDaoImpl, cause: " + e.getMessage(), e);
			throw new DaoException("Query failed", e);
		}
		return module;

	}
	
}
